篇首语:本文由编程笔记#小编为大家整理,主要介绍了分布式定时任务调度框架Quartz学习与实战记录完整篇相关的知识,希望对你有一定的参考价值。
Quartz就是一个基于Java实现的任务调度框架,用于执行你想要执行的任何任务。
Quartz是OpenSymphony开源组织在Job scheduling(定时调度)领域的开源项目,它可以与J2EE和J2SE应用程序相结合也可以单独使用。
Quartz是开源且具有丰富特性的任务调度库,能够集成任何的Java应用。它能创建简单的或者复杂的调度任务,以执行上十,上百,上千,上万的任务。任务job被定义为标准的Java组件。能工执行任何你想要实现的功能。Quartz调度框架包含许多企业级的特性,如JTA事务,集群的支持。
官网:http://www.quartz-scheduler.org/
job就是你想实现的任务类,每一个job必须实现org.quartz.job接口,且只需实现接口定义的execute()方法
Trigger为你执行任务的触发器(定时)
Trigger主要包含两个SimpleTrigger和CronTrigger两种
Scheduler为定时任务调度,它会将任务Job及触发器Trigger整合起来,负责基于Trigger设定的时间来执行Job
Scheduler:用于定时调度程序交互的主程序接口。Scheduler调度程序:任务执行计划表,只有安排进执行计划的任务Job【通过scheduler.scheduleJob方法安排进执行任务】,当它预先定义的执行时间到了的时候(任务出发trigger)该任务才会被执行
Job:预先定义的,希望在未来某个使劲能被调度程序执行的任务类,可自定义
JobDetail:使用JobDetail来定义定时任务的实例,JobDetail实例是通过JobBuilder类创建的
JobDataMap:可以包含不限量(序列化的)的数对象,在Job实例执行的时候,可以使用其中的数据;JobDataMap是Java Map接口的一个实现,额外增加了一些便于存取基本类型数据的方法
Trigger:触发器,Trigger对象是用来触发执行Job的。当调度一个Job时,我们实例一个触发器然后调整他的属性来满足Job执行的条件。表明任务在什么时候会执行。【定义了一个已经被安排的任务将会在什么时候执行的时间条件】
JobBuilder:用于声明一个任务实例,也可以定义关于该任务的详情比如任务名,组名等。通过JobBuilder声明的实例将会作为一个实际执行的任务。
TriggerBuilder:触发器创建器,用于创建触发器trigger实例
JobListener、TriggerListener、SchedulerListener监听器,用于对组件的监听
构建一个任务类实现Job接口,重写execute(执行方法)方法,在执行方法中编写定时调度需要实现的逻辑。
创建一个main方法,在main方法中构建任务实例和处方实例有调度器实例进行绑定并开启任务。
<dependency>
<groupId>org.quartz-schedulergroupId>
<artifactId>quartzartifactId>
<version>2.3.0version>
dependency>
<dependency>
<groupId>org.quartz-schedulergroupId>
<artifactId>quartz-jobsartifactId>
<version>2.3.0version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
/**
* &#64;Author ScholarTang
* &#64;Date 2021/7/13 10:45
* &#64;Desc 任务类
*/
&#64;Slf4j
public class HelloJob implements Job
&#64;Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException
log.info(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) &#43; " | 任务被执行了");
/**
* &#64;Author ScholarTang
* &#64;Date 2021/7/13 10:53
* &#64;Desc 调度器
*/
public class HelloSchedulerDemo
public static void main(String[] args) throws SchedulerException
//从调度工厂中获取调度器实例
Scheduler scheduler &#61; StdSchedulerFactory.getDefaultScheduler();
//通过JobBuilder构建一个任务实例
JobDetail jobDetail &#61; JobBuilder.newJob(HelloJob.class)
//设置任务的唯一实例名称和任务组名称组名
.withIdentity("job1", "group1")
//构建实例
.build();
//通过TriggerBuilder构建触发器实例
SimpleTrigger trigger &#61; TriggerBuilder.newTrigger()
//设置触发器唯一实例名称和触发器的组名
.withIdentity("trigger1", "group1")
//执行计划&#xff0c;每五秒执行一次
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5))
//立即执行
.startNow()
//构建实例
.build();
//调度器绑定任务实例和触发器
scheduler.scheduleJob(jobDetail,trigger);
//开启定时任务
scheduler.start();
&#64;Slf4j
public class HelloJob implements Job
public HelloJob()
log.info("实例被创建了");
&#64;Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException
log.info(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) &#43; " | 任务被执行了");
&#64;Slf4j
public class HelloSchedulerDemo
public static void main(String[] args) throws SchedulerException
//从调度工厂中获取调度器实例
Scheduler scheduler &#61; StdSchedulerFactory.getDefaultScheduler();
//通过JobBuilder构建一个任务实例
JobDetail jobDetail &#61; JobBuilder.newJob(HelloJob.class)
//设置任务的唯一实例名称和任务组名称组名
.withIdentity("job1", "group1")
//构建实例
.build();
//jobDataMap
JobDataMap jobDataMap &#61; jobDetail.getJobDataMap();
//任务实例的唯一标识名称
String name &#61; jobDetail.getKey().getName();
//任务调度实例的组名
String group &#61; jobDetail.getKey().getGroup();
//任务类信息
String clazzName &#61; jobDetail.getKey().getClass().getName();
log.info("jobDataMap:", jobDataMap);
log.info("任务实例的唯一标识名称&#xff1a;"&#43;name);
log.info("任务调度实例的组名&#xff1a;"&#43;group);
log.info("任务类信息&#xff1a;"&#43;clazzName);
//通过TriggerBuilder构建触发器实例
SimpleTrigger trigger &#61; TriggerBuilder.newTrigger()
//设置触发器唯一实例名称和触发器的组名
.withIdentity("trigger1", "group1")
//执行计划&#xff0c;每五秒执行一次
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5))
//立即执行
.startNow()
//构建实例
.build();
//调度器绑定任务实例和触发器
scheduler.scheduleJob(jobDetail,trigger);
//开启定时任务
scheduler.start();
当Scheduler调用一个Job&#xff0c;就会将JobExecutionContext传递给Job的execute()方法
Job能通过JobExecuteContext对象访问到Quartz运行时的环境
以及Job本身的明细数据
/**
* &#64;Author ScholarTang
* &#64;Date 2021/7/13 10:45
* &#64;Desc 任务类
*/
&#64;Slf4j
public class HelloJob implements Job
&#64;Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException
//通过JobExecutionContext获取JobDetail
JobDetail jobDetail &#61; jobExecutionContext.getJobDetail();
JobKey jobKey &#61; jobDetail.getKey();
String jobDetailName &#61; jobKey.getName();
String jobDetailGroup &#61; jobKey.getGroup();
String jobClazzNameJobDetail &#61; jobKey.getClass().getName();
log.info("任务实例的唯一标识名称&#xff1a;" &#43; jobDetailName);
log.info("任务实例的组名&#xff1a;" &#43; jobDetailGroup);
log.info("任务实例绑定的任务类信息&#xff1a;" &#43; jobClazzNameJobDetail);
log.info("-----------------------------------------");
//通过JobExecutionContext获取Trigger
Trigger trigger &#61; jobExecutionContext.getTrigger();
TriggerKey triggerKey &#61; trigger.getKey();
String triggerKeyName &#61; triggerKey.getName();
String triggerKeyGroup &#61; triggerKey.getGroup();
String triggerClazzName &#61; triggerKey.getClass().getName();
log.info("触发器的唯一标识名称&#xff1a;" &#43; triggerKeyName);
log.info("触发器的组名&#xff1a;" &#43; triggerKeyGroup);
log.info("触发器绑定的任务类信息&#xff1a;" &#43; triggerClazzName);
log.info("-----------------------------------------");
//通过JobExecutionContext
String jobClazzName &#61; jobExecutionContext.getClass().getName();
log.info("job类相关的信息&#xff1a;"&#43;jobClazzName);
log.info("-----------------------------------------");
log.info(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) &#43; " | 任务被执行了");
/**
* &#64;Author ScholarTang
* &#64;Date 2021/7/13 10:53
* &#64;Desc 调度器
*/
&#64;Slf4j
public class HelloSchedulerDemo
public static void main(String[] args) throws SchedulerException
//从调度工厂中获取调度器实例
Scheduler scheduler &#61; StdSchedulerFactory.getDefaultScheduler();
//通过JobBuilder构建一个任务实例
JobDetail jobDetail &#61; JobBuilder.newJob(HelloJob.class)
//设置任务的唯一实例名称和任务组名称组名
.withIdentity("job1", "group1")
//设置jobDataMap数据 <<&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
.usingJobData("message","勇敢牛牛、不怕困难")
//构建实例
.build();
//通过TriggerBuilder构建触发器实例
SimpleTrigger trigger &#61; TriggerBuilder.newTrigger()
//设置触发器唯一实例名称和触发器的组名
.withIdentity("trigger1", "group1")
//设置jobDataMap数据 <<&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
.usingJobData("username","张三")
//执行计划&#xff0c;每五秒执行一次
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5))
//立即执行
.startNow()
//构建实例
.build();
//调度器绑定任务实例和触发器
scheduler.scheduleJob(jobDetail,trigger);
//开启定时任务
scheduler.start();
/**
* &#64;Author ScholarTang
* &#64;Date 2021/7/13 10:45
* &#64;Desc 任务类
*/
&#64;Slf4j
public class HelloJob implements Job
&#64;Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException
//通过JobExecutionContext获取JobDetail
JobDetail jobDetail &#61; jobExecutionContext.getJobDetail();
JobKey jobKey &#61; jobDetail.getKey();
String jobDetailName &#61; jobKey.getName();
String jobDetailGroup &#61; jobKey.getGroup();
String jobClazzNameJobDetail &#61; jobKey.getClass().getName();
log.info("任务实例的唯一标识名称&#xff1a;" &#43; jobDetailName);
log.info("任务实例的组名&#xff1a;" &#43; jobDetailGroup);
log.info("任务实例绑定的任务类信息&#xff1a;" &#43; jobClazzNameJobDetail);
log.info("-----------------------------------------");
//通过JobExecutionContext获取Trigger
Trigger trigger &#61; jobExecutionContext.getTrigger();
TriggerKey triggerKey &#61; trigger.getKey();
String triggerKeyName &#61; triggerKey.getName();
String triggerKeyGroup &#61; triggerKey.getGroup();
String triggerClazzName &#61; triggerKey.getClass().getName();
log.info("触发器的唯一标识名称&#xff1a;" &#43; triggerKeyName);
log.info("触发器的组名&#xff1a;" &#43; triggerKeyGroup);
log.info("触发器绑定的任务类信息&#xff1a;" &#43; triggerClazzName);
log.info("-----------------------------------------");
//通过JobExecutionContext
String jobClazzName &#61; jobExecutionContext.getClass().getName();
log.info("job类相关的信息&#xff1a;"&#43;jobClazzName);
log.info("-----------------------------------------");
//获取JobDetail中JobDataMap中的message内容 <<&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
JobDataMap jobDataMap &#61; jobDetail.getJobDataMap();
String message &#61; jobDataMap.getString("message");
log.info("从JobDetail-JobDataMap中或到的message内容为&#xff1a;" &#43; message);
//获取Trigger中JobDataMap中的username内容 <<&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
JobDataMap triggerJobDataMap &#61; trigger.getJobDataMap();
String username &#61; triggerJobDataMap.getString("username");
log.info("从Trigger-JobDataMap中获取到的username内容为&#xff1a;" &#43; username);
log.info("-----------------------------------------");
log.info(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) &#43; " | 任务被执行了");
调度器的内容是不变的。
注意&#xff1a;如果任务实例和触发器的JobDataMap中使用的是同一个key那么触发器的JobDataMap值会覆盖掉任务实例的值
/**
* &#64;Author ScholarTang
* &#64;Date 2021/7/13 10:45
* &#64;Desc 任务类
*/
&#64;Slf4j
public class HelloJob implements Job
private String message;
private String username;
public void setMessage(String message)
this.message &#61; message;
public void setUsername(String username)
this.username &#61; username;
&#64;Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException
//通过JobExecutionContext获取JobDetail
JobDetail jobDetail &#61; jobExecutionContext.getJobDetail();
JobKey jobKey &#61; jobDetail.getKey();
String jobDetailName &#61; jobKey.getName();
String jobDetailGroup &#61; jobKey.getGroup();
String jobClazzNameJobDetail &#61; jobKey.getClass().getName();
log.info("任务实例的唯一标识名称&#xff1a;" &#43; jobDetailName);
log.info("任务实例的组名&#xff1a;" &#43; jobDetailGroup);
log.info("任务实例绑定的任务类信息&#xff1a;" &#43; jobClazzNameJobDetail);
log.info("-----------------------------------------");
//通过JobExecutionContext获取Trigger
Trigger trigger &#61; jobExecutionContext.getTrigger();
TriggerKey triggerKey &#61; trigger.getKey();
String triggerKeyName &#61; triggerKey.getName();
String triggerKeyGroup &#61; triggerKey.getGroup();
String triggerClazzName &#61; triggerKey.getClass().getName();
log.info("触发器的唯一标识名称&#xff1a;" &#43; triggerKeyName);
log.info("触发器的组名&#xff1a;" &#43; triggerKeyGroup);
log.info("触发器绑定的任务类信息&#xff1a;" &#43; triggerClazzName);
log.info("-----------------------------------------");
//通过JobExecutionContext
String jobClazzName &#61; jobExecutionContext.getClass().getName();
log.info("job类相关的信息&#xff1a;"&#43;jobClazzName)